﻿using System;
using System.Collections.Generic;
using Microsoft.Scripting;

namespace Scala.Compiler
{
    public enum TokenKind
    {
        #region Common Tokens

        EMPTY = -3,
        UNDEF = -2,
        ERROR = -1,
        EOF = 0,

        CHARLIT = 1,
        INTLIT = 2,
        LONGLIT = 3,
        FLOATLIT = 4,
        DOUBLELIT = 5,
        STRINGLIT = 6,

        NEW  =20,
        THIS = 21,
        SUPER =23,
        NULL = 24,
        TRUE = 25,
        FALSE = 26,

        PROTECTED = 43,
        PRIVATE = 44,
        ABSTRACT = 46,
        FINAL = 49,

        PACKAGE = 60,
        IMPORT = 61,
        CLASS = 62,
        EXTENDS = 68,

        IF = 80,
        ELSE = 82,
        WHILE = 83,
        DO = 84,
        FOR = 85,
        THROW = 90,
        TRY = 91,
        CATCH = 92,
        FINALLY = 93,
        CASE = 96,
        RETURN = 97,

        LPAREN = 100,
        RPAREN = 101,
        LBRACKET = 102,
        RBRACKET = 103,
        LBRACE = 104,
        RBRACE = 105,

        COMMA = 120,
        SEMI = 121,
        DOT = 122,
        COLON = 123,
        EQUALS = 124,
        AT = 125,

#endregion
        STRINGPART = 7,
        SYMBOLLIT = 8,
        INTERPOLATIONID  = 9,
        
        IDENTIFIER = 10,
        BACKQUOTED_IDENT = 11,

        IMPLICIT = 40,
        OVERRIDE = 41,
        SEALED = 45,
        LAZY = 55,
        MACRO = 57,

        CASECLASS = 63,
        OBJECT = 64,
        CASEOBJECT = 65,
        TRAIT = 66,
        WITH = 69,
        TYPE = 70,
        FORSOME = 71,
        DEF = 72,
        VAL = 73,
        VAR = 74,

        THEN = 81,
        YIELD = 86,
        MATCH = 95,

        HASH = 130,
        USCORE = 131,
        ARROW = 132,
        LARROW = 133,
        SUBTYPE = 134,
        SUPERTYPE = 135,
        VIWEBOUND = 136,
        NEWLINE = 137,
        NEWLINES = 138,
        XMLSTART = 139,

        COMMENT = 200,
        WHITESPACE = 201,
        IGNORE = 202,
        ESCAPE = 203,

        Error = 250,
        Name = 251,
        Constant = 252,
        NLTOKEN
    }

    public static class Tokens
    {
        public static readonly Token EndOfFileToken = new SymbolToken(TokenKind.EOF, "<eof>");
        public static readonly Token NewLineToken = new SymbolToken(TokenKind.NEWLINE, "<newline>");
        public static readonly Token NLToken = new SymbolToken(TokenKind.NLTOKEN, "<NL>");
        public static readonly Token CommentToken = new SymbolToken(TokenKind.COMMENT, "<commment>");
        public static readonly Token DotToken = new SymbolToken(TokenKind.DOT, ".");

        public static readonly Token SemiToken = new SymbolToken(TokenKind.SEMI, ";");
        public static readonly Token CommaToken = new SymbolToken(TokenKind.COMMA, ",");
        public static readonly Token LparenToken = new SymbolToken(TokenKind.LPAREN, "(");
        public static readonly Token LbraceToken = new SymbolToken(TokenKind.LBRACE, "{");
        public static readonly Token LbracketToken = new SymbolToken(TokenKind.LBRACKET, "[");
        public static readonly Token RparenToken = new SymbolToken(TokenKind.RPAREN, ")");
        public static readonly Token RbraceToken = new SymbolToken(TokenKind.RBRACE, "}");
        public static readonly Token RbracketToken = new SymbolToken(TokenKind.RBRACKET, "]");
        public static readonly Token ArrowToken = new SymbolToken(TokenKind.ARROW, "\u21D2");
        public static readonly Token LarrowToken = new SymbolToken(TokenKind.LARROW, "\u2190");

        public static readonly Token Abstractkw = new SymbolToken(TokenKind.ABSTRACT, "abstract");
        public static readonly Token Casekw = new SymbolToken(TokenKind.CASE, "case");
        public static readonly Token Classkw = new SymbolToken(TokenKind.CLASS, "class");
        public static readonly Token Catchkw = new SymbolToken(TokenKind.CATCH, "catch");
        public static readonly Token Defkw = new SymbolToken(TokenKind.DEF, "def");
        public static readonly Token Dokw = new SymbolToken(TokenKind.DO, "do");
        public static readonly Token Elsekw = new SymbolToken(TokenKind.ELSE, "else");
        public static readonly Token Extendskw = new SymbolToken(TokenKind.EXTENDS, "extends");
        public static readonly Token Falsekw = new SymbolToken(TokenKind.FALSE, "false");
        public static readonly Token Finalkw = new SymbolToken(TokenKind.FINAL, "final");
        public static readonly Token Finallykw = new SymbolToken(TokenKind.FINALLY, "finally");
        public static readonly Token Forkw = new SymbolToken(TokenKind.FOR, "for");
        public static readonly Token ForSomekw = new SymbolToken(TokenKind.FORSOME, "forSome");
        public static readonly Token Ifkw = new SymbolToken(TokenKind.IF, "if");
        public static readonly Token Implicitkw = new SymbolToken(TokenKind.IMPLICIT, "implicit");
        public static readonly Token Importkw = new SymbolToken(TokenKind.IMPORT, "import");
        public static readonly Token Lazykw = new SymbolToken(TokenKind.LAZY, "lazy");
        public static readonly Token Macrokw = new SymbolToken(TokenKind.MACRO, "macro");
        public static readonly Token Matchkw = new SymbolToken(TokenKind.MATCH, "match");
        public static readonly Token Newkw = new SymbolToken(TokenKind.NEW, "new");
        public static readonly Token Nullkw = new SymbolToken(TokenKind.NULL, "null");
        public static readonly Token Objectkw = new SymbolToken(TokenKind.OBJECT, "object");
        public static readonly Token Overridekw = new SymbolToken(TokenKind.OVERRIDE, "override");
        public static readonly Token Packagekw = new SymbolToken(TokenKind.PACKAGE, "package");
        public static readonly Token Privatekw = new SymbolToken(TokenKind.PRIVATE, "private");
        public static readonly Token Protectedkw = new SymbolToken(TokenKind.PROTECTED, "protected");
        public static readonly Token Returnkw = new SymbolToken(TokenKind.RETURN, "return");
        public static readonly Token Sealedkw = new SymbolToken(TokenKind.SEALED, "sealed");
        public static readonly Token Superkw = new SymbolToken(TokenKind.SUPER, "super");
        public static readonly Token Thenkw = new SymbolToken(TokenKind.THEN, "then");
        public static readonly Token Thiskw = new SymbolToken(TokenKind.THIS, "this");
        public static readonly Token Throwkw = new SymbolToken(TokenKind.THROW, "throw");
        public static readonly Token Traitkw = new SymbolToken(TokenKind.TRAIT, "trait");
        public static readonly Token Truekw = new SymbolToken(TokenKind.TRUE, "true");
        public static readonly Token Trykw = new SymbolToken(TokenKind.TRY, "try");
        public static readonly Token Typekw = new SymbolToken(TokenKind.TYPE, "type");
        public static readonly Token Valkw = new SymbolToken(TokenKind.VAL, "val");
        public static readonly Token Varkw = new SymbolToken(TokenKind.VAR, "var");
        public static readonly Token Withkw = new SymbolToken(TokenKind.WITH, "with");
        public static readonly Token Whilekw = new SymbolToken(TokenKind.WHILE, "while");
        public static readonly Token Yieldkw = new SymbolToken(TokenKind.YIELD, "yield");
        public static readonly Token Dotkw = new SymbolToken(TokenKind.DOT, ".");
        public static readonly Token UScorekw = new SymbolToken(TokenKind.USCORE, "_");
        public static readonly Token Colonkw = new SymbolToken(TokenKind.COLON, ":");
        public static readonly Token Equalskw = new SymbolToken(TokenKind.EQUALS, "=");
        public static readonly Token Arrowkw = new SymbolToken(TokenKind.ARROW, "=>");
        public static readonly Token LArrowkw = new SymbolToken(TokenKind.LARROW, "<-");
        public static readonly Token SubTypekw = new SymbolToken(TokenKind.SUBTYPE, "<:");
        public static readonly Token ViewBoundkw = new SymbolToken(TokenKind.VIWEBOUND, "<%");
        public static readonly Token SuperTypekw = new SymbolToken(TokenKind.SUPERTYPE, ">:");
        public static readonly Token Hashkw = new SymbolToken(TokenKind.HASH, "#");
        public static readonly Token Atkw = new SymbolToken(TokenKind.AT, "@");

        public static readonly Dictionary<string, Token> AllKeywords = new Dictionary<string, Token>();

        public static void Addkeywords()
        {
            AllKeywords.Add("abstract", Abstractkw);
            AllKeywords.Add("case", Casekw);
            AllKeywords.Add("class", Classkw);
            AllKeywords.Add("catch", Catchkw);
            AllKeywords.Add("def", Defkw);
            AllKeywords.Add("do", Dokw);
            AllKeywords.Add("else", Elsekw);
            AllKeywords.Add("extends", Extendskw);
            AllKeywords.Add("false", Falsekw);
            AllKeywords.Add("final", Finalkw);
            AllKeywords.Add("finally", Finallykw);
            AllKeywords.Add("for", Forkw);
            AllKeywords.Add("forSome", ForSomekw);
            AllKeywords.Add("if", Ifkw);
            AllKeywords.Add("implicit", Implicitkw);
            AllKeywords.Add("import", Importkw);
            AllKeywords.Add("lazy", Lazykw);
            AllKeywords.Add("macro", Macrokw);
            AllKeywords.Add("match", Matchkw);
            AllKeywords.Add("new", Newkw);
            AllKeywords.Add("null", Nullkw);
            AllKeywords.Add("object", Objectkw);
            AllKeywords.Add("override", Overridekw);
            AllKeywords.Add("package", Packagekw);
            AllKeywords.Add("private", Privatekw);
            AllKeywords.Add("protected", Protectedkw);
            AllKeywords.Add("return", Returnkw);
            AllKeywords.Add("sealed", Sealedkw);
            AllKeywords.Add("super", Superkw);
            AllKeywords.Add("then", Thenkw);
            AllKeywords.Add("this", Thiskw);
            AllKeywords.Add("throw", Throwkw);
            AllKeywords.Add("trait", Traitkw);
            AllKeywords.Add("true", Truekw);
            AllKeywords.Add("try", Trykw);
            AllKeywords.Add("type", Typekw);
            AllKeywords.Add("val", Valkw);
            AllKeywords.Add("var", Varkw);
            AllKeywords.Add("with", Withkw);
            AllKeywords.Add("while", Whilekw);
            AllKeywords.Add("yield", Yieldkw);
            AllKeywords.Add(".", Dotkw);
            AllKeywords.Add("_", UScorekw);
            AllKeywords.Add(":", Colonkw);
            AllKeywords.Add("=", Equalskw);
            AllKeywords.Add("=>", Arrowkw);
            AllKeywords.Add("<-", LArrowkw);
            AllKeywords.Add("<:", SubTypekw);
            AllKeywords.Add("<%", ViewBoundkw);
            AllKeywords.Add(">:", SuperTypekw);
            AllKeywords.Add("#", Hashkw);
            AllKeywords.Add("@", Atkw);
        }
    }
    
}
